package com.sample.view.components
{
	import flash.events.Event;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.controls.Tree;
	import mx.events.CollectionEvent;
	import mx.events.ListEvent;

	[Event(name="select", type="com.sample.view.components.NavEvent")]
	[DefaultProperty("nodes")]
	public class NavTree extends Tree
	{
		[Embed("/../images/bullet_black.png")]
        private var LEAF_ICON:Class;
        
        private var childLists:Array = [];
        private var namedNodes:Object;
        private var xml:XML;
		
		public function NavTree()
		{
			super();
			
			labelField = "@label";
			showRoot = false;
			
			setStyle("defaultLeafIcon", null);
			setStyle("folderOpenIcon", null);
			setStyle("folderClosedIcon", null);
			
			addEventListener(ListEvent.CHANGE, selectionChanged);
		}
		
		[Inspectable]
		[ArrayElementType("com.sample.view.components.NavNode")]
		public function set nodes(value:Array):void {
			xml = <root></root>;
			
			for each (var node:NavNode in value) {
				xml.appendChild(node.getXML());
			}
			
			dataProvider = xml;
			
			namedNodes = {};
			for each (var child:NavNode in value) {
				namedNodes[child.name] = child;
				for each (var descendant:NavNode in child.getDescendants()) {
					namedNodes[descendant.name] = descendant;
				}
			}
		}
		
		public function listChangeHandler(event:CollectionEvent):void {
			var list:ICollectionView = event.target as ICollectionView;
			
			for each(var child in childLists) {
				if(child.list == list)
					updateChildList(child.name, child.list, child.func);
			}
		}
		
		public function addChildrenList(name:String, children:ICollectionView, func:Function):void {
			children.addEventListener(CollectionEvent.COLLECTION_CHANGE, listChangeHandler);
			childLists.push({name:name, list:children, func:func});
			
			updateChildList(name, children, func);
		}
		
		private function updateChildList(name:String, children:ICollectionView, func:Function):void {
			var childrenNodes:ArrayCollection = new ArrayCollection();
			var newNode:NavNode = new NavNode();
			
			for(var i:int = 0; i < children.length; i++) {
				newNode = func(children[i]);
				childrenNodes.addItem(newNode);
			}
			
			var parentNode:NavNode = namedNodes[name];
			
			for each (var child:NavNode in parentNode.children)
				delete namedNodes[child.name];
			parentNode.children = childrenNodes.source;
			
			var parentXML:XML = xml..node.(@name == name)[0];
			
			delete parentXML.node;

			for each (var node:NavNode in childrenNodes) {
				parentXML.appendChild(node.getXML());
			}
			
			dataProvider = xml;			
			
		}
		
		private function selectionChanged(event:Event) {
			var name:String = selectedItem.@name;
			dispatchEvent(new NavEvent("select", name));
			var node:NavNode = namedNodes[name];
			if (node != null) {
				node.fire();
			}
		}
		
	}
}